﻿using GamFi.API.Application.Contracts.Token.GetTokenById;
using GamFi.API.Application.Exceptions;
using GamFi.API.Application.Interfaces;
using GamFi.API.Application.Resources;
using MediatR;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Localization;

namespace GamFi.API.Application.Features.Queries.Token.GetTokenById;

/// <summary>
/// Обработчик для <see cref="GetTokenByIdQuery"/>
/// </summary>
public class GetTokenByIdQueryHandler(IDbContext dbContext, IStringLocalizer<ExceptionMessages> localizer) : IRequestHandler<GetTokenByIdQuery, GetTokenByIdResponse>
{
    /// <summary>Handles a request</summary>
    /// <param name="request">The request</param>
    /// <param name="cancellationToken">Cancellation token</param>
    /// <returns>Response from the request</returns>
    public async Task<GetTokenByIdResponse> Handle(GetTokenByIdQuery request, CancellationToken cancellationToken)
    {
        if (request is null)
            throw new RequestException(localizer[nameof(RequestException.RequestIsEmpty)]);
        
        var token = await dbContext.Tokens.FirstOrDefaultAsync(t => t.Id == request.Id, cancellationToken);

        if (token is null)
            return new GetTokenByIdResponse { IsFound = false };

        var count = dbContext.Purchases
            .Where(p => p.TokenId == token.Id)
            .AsEnumerable()
            .DistinctBy(p => p.WalletId)
            .Count();

        return new GetTokenByIdResponse
        {
            IsFound = true,
            Id = token.Id,
            Name = token.Name,
            TokenPrice = token.TokenPrice,
            TokenSymbol = token.TokenSymbol,
            ChainId = token.ChainId,
            TargetedRaise = token.TargetedRaise,
            TotalRaise = token.TotalRaise,
            TokenSummary = token.TokenSummary,
            CreatedBy = token.CreatedBy ?? Guid.Empty,
            CreatedDate = token.CreatedDate ?? DateTime.MinValue,
            ImageId = token.ImageId,
            Participants = count
        };
    }
}